using System;
using System.Collections;
using System.Diagnostics;
using System.IO;
using System.Threading;
using System.Timers;
using System.Windows.Forms;
namespace SilverSea.Video.Tools
{
	public class FFMPEG
	{
		public string vcodec = "mp4v";
		public string vtag = string.Empty;
		public int vb = 128;
		public string acodec = "mp4a";
		public int ab = 128;
		public int audioChanel = 2;
		public int audioSampleRate = 44100;
		public bool multiThreadEncoding = true;
		public bool encodingWithSameQuality = true;
		public string h264preset = "libx264-veryfast.ffpreset";
		private Process process_0;
		public FFMPEGTask currentFFMPEGTask;
		private EncodingCompleteEventHandler encodingCompleteEventHandler_0;
		private ErrorEventHandler errorEventHandler_0;
		private Queue queue_0 = new Queue();
		private System.Timers.Timer timer_0 = new System.Timers.Timer();
		public event EncodingCompleteEventHandler EncodingComplete
		{
			add
			{
				EncodingCompleteEventHandler encodingCompleteEventHandler = this.encodingCompleteEventHandler_0;
				EncodingCompleteEventHandler encodingCompleteEventHandler2;
				do
				{
					encodingCompleteEventHandler2 = encodingCompleteEventHandler;
					EncodingCompleteEventHandler value2 = (EncodingCompleteEventHandler)Delegate.Combine(encodingCompleteEventHandler2, value);
					encodingCompleteEventHandler = Interlocked.CompareExchange<EncodingCompleteEventHandler>(ref this.encodingCompleteEventHandler_0, value2, encodingCompleteEventHandler2);
				}
				while (encodingCompleteEventHandler != encodingCompleteEventHandler2);
			}
			remove
			{
				EncodingCompleteEventHandler encodingCompleteEventHandler = this.encodingCompleteEventHandler_0;
				EncodingCompleteEventHandler encodingCompleteEventHandler2;
				do
				{
					encodingCompleteEventHandler2 = encodingCompleteEventHandler;
					EncodingCompleteEventHandler value2 = (EncodingCompleteEventHandler)Delegate.Remove(encodingCompleteEventHandler2, value);
					encodingCompleteEventHandler = Interlocked.CompareExchange<EncodingCompleteEventHandler>(ref this.encodingCompleteEventHandler_0, value2, encodingCompleteEventHandler2);
				}
				while (encodingCompleteEventHandler != encodingCompleteEventHandler2);
			}
		}
		public event ErrorEventHandler LastError
		{
			add
			{
				ErrorEventHandler errorEventHandler = this.errorEventHandler_0;
				ErrorEventHandler errorEventHandler2;
				do
				{
					errorEventHandler2 = errorEventHandler;
					ErrorEventHandler value2 = (ErrorEventHandler)Delegate.Combine(errorEventHandler2, value);
					errorEventHandler = Interlocked.CompareExchange<ErrorEventHandler>(ref this.errorEventHandler_0, value2, errorEventHandler2);
				}
				while (errorEventHandler != errorEventHandler2);
			}
			remove
			{
				ErrorEventHandler errorEventHandler = this.errorEventHandler_0;
				ErrorEventHandler errorEventHandler2;
				do
				{
					errorEventHandler2 = errorEventHandler;
					ErrorEventHandler value2 = (ErrorEventHandler)Delegate.Remove(errorEventHandler2, value);
					errorEventHandler = Interlocked.CompareExchange<ErrorEventHandler>(ref this.errorEventHandler_0, value2, errorEventHandler2);
				}
				while (errorEventHandler != errorEventHandler2);
			}
		}
		public bool IsRunning
		{
			get
			{
				return this.process_0 != null && !this.process_0.HasExited;
			}
		}
		public int Count
		{
			get
			{
				return this.queue_0.Count;
			}
		}
		public void AddVideo(string videoFile, int cameraID, string cameraName, int recordingRate, string recordingSize, bool enableAudio)
		{
			string text = videoFile.Replace(".avi", "to").Replace(".mp4", "to");
			text = text + DateTime.Now.ToString("yyyyMMdd_HHmmss") + ".mp4";
			string text2 = " -i " + videoFile;
			if (this.multiThreadEncoding && Environment.ProcessorCount > 1)
			{
				text2 = text2 + " -threads " + Environment.ProcessorCount;
			}
			if (this.vcodec == "mp4v")
			{
				text2 += " -vcodec mpeg4";
			}
			else
			{
				if (this.vcodec == "x264" || this.vcodec == "h264")
				{
					text2 += " -vcodec libx264";
					if (this.h264preset != string.Empty)
					{
						text2 = text2 + " -fpre " + this.h264preset;
					}
				}
			}
			if (this.vtag != string.Empty)
			{
				text2 = text2 + " -vtag " + this.vtag;
			}
			text2 = text2 + " -r " + recordingRate;
			if (recordingSize != string.Empty)
			{
				text2 = text2 + " -s " + recordingSize;
			}
			if (enableAudio)
			{
				if (this.acodec == "mp4a")
				{
					text2 += " -acodec aac";
				}
				else
				{
					text2 = text2 + " -acodec " + this.acodec;
				}
				object obj = text2;
				text2 = string.Concat(new object[]
				{
					obj,
					" -ac ",
					this.audioChanel,
					" -ar ",
					this.audioSampleRate,
					" -ab ",
					this.ab,
					" "
				});
			}
			else
			{
				text2 += " -an ";
			}
			if (this.encodingWithSameQuality)
			{
				text2 += "-sameq ";
			}
			text2 += text;
			this.queue_0.Enqueue(new FFMPEGTask(Application.StartupPath + "\\ffmpeg\\ffmpeg.exe", text2, videoFile, text, true, cameraID, cameraName));
		}
		public void Start()
		{
			this.timer_0.Interval = 1000.0;
			this.timer_0.Elapsed += new ElapsedEventHandler(this.timer_0_Elapsed);
			this.timer_0.Start();
		}
		public void Stop()
		{
			this.timer_0.Elapsed -= new ElapsedEventHandler(this.timer_0_Elapsed);
			this.timer_0.Stop();
		}
		private void timer_0_Elapsed(object sender, EventArgs e)
		{
			if (this.queue_0.Count > 0 && !this.IsRunning)
			{
				FFMPEGTask fFMPEGTask = (FFMPEGTask)this.queue_0.Dequeue();
				if (File.Exists(fFMPEGTask.srcVideoFile))
				{
					this.method_0(fFMPEGTask.dstVideoFile);
					this.ProcessTask(fFMPEGTask);
				}
			}
		}
		public void ProcessTask(object taskObject)
		{
			this.process_0 = new Process();
			try
			{
				FFMPEGTask fFMPEGTask = (FFMPEGTask)taskObject;
				this.currentFFMPEGTask = fFMPEGTask;
				this.process_0.StartInfo.FileName = fFMPEGTask.commandLine;
				this.process_0.StartInfo.Arguments = fFMPEGTask.args;
				this.process_0.StartInfo.CreateNoWindow = true;
				this.process_0.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
				this.process_0.StartInfo.UseShellExecute = false;
				this.process_0.StartInfo.RedirectStandardOutput = true;
				this.process_0.StartInfo.RedirectStandardError = true;
				this.process_0.Exited += new EventHandler(this.process_0_Exited);
				this.process_0.ErrorDataReceived += new DataReceivedEventHandler(this.process_0_ErrorDataReceived);
				this.process_0.OutputDataReceived += new DataReceivedEventHandler(this.process_0_OutputDataReceived);
				this.process_0.EnableRaisingEvents = true;
				this.process_0.Start();
				this.process_0.PriorityClass = ProcessPriorityClass.BelowNormal;
				this.process_0.BeginOutputReadLine();
				this.process_0.BeginErrorReadLine();
			}
			catch (Exception ex)
			{
				if (this.errorEventHandler_0 != null)
				{
					this.errorEventHandler_0(this, "Error while ecoding video with ffmpeg: " + ex.ToString());
				}
			}
		}
		private void process_0_Exited(object sender, EventArgs e)
		{
			if (this.encodingCompleteEventHandler_0 != null)
			{
				this.encodingCompleteEventHandler_0(this.currentFFMPEGTask);
			}
			if (this.process_0 != null)
			{
				this.process_0.Dispose();
				this.process_0 = null;
			}
			this.method_0(this.currentFFMPEGTask.srcVideoFile);
		}
		private void process_0_ErrorDataReceived(object sender, DataReceivedEventArgs e)
		{
		}
		private void process_0_OutputDataReceived(object sender, DataReceivedEventArgs e)
		{
		}
		private bool method_0(string string_0)
		{
			bool result = false;
			try
			{
				if (File.Exists(string_0))
				{
					File.Delete(string_0);
				}
				result = true;
			}
			catch (Exception ex)
			{
				result = false;
				if (this.errorEventHandler_0 != null)
				{
					this.errorEventHandler_0(this, ex.Message);
				}
			}
			return result;
		}
	}
}
